#include "zigbee_manager.h"

#include "esp_log.h"
#include "esp_zigbee_core.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ha/esp_zigbee_ha_standard.h"

static const char *TAG = "ZB_MANAGER";

#define NVS_NAMESPACE "zb_devices"
#define NVS_KEY_DEVICES "devices"
#define NVS_KEY_COUNT "count"

// 用户注册的回调函数指针
static zb_coordinator_start_cb_t s_start_cb = NULL;
static zb_device_join_cb_t s_join_cb = NULL;
static zb_device_leave_cb_t s_leave_cb = NULL;
static zb_zcl_receive_cb_t s_receive_cb = NULL;

bool get_esp_zb_ieee_addr(uint16_t short_addr, char *out_str, size_t len) {
	for (int i = 0; i < s_device_count; i++) {
		if (s_devices[i].short_addr == short_addr) {
			snprintf(out_str, len, "%02X%02X%02X%02X%02X%02X%02X%02X",
					 s_devices[i].ieee_addr[7], s_devices[i].ieee_addr[6],
					 s_devices[i].ieee_addr[5], s_devices[i].ieee_addr[4],
					 s_devices[i].ieee_addr[3], s_devices[i].ieee_addr[2],
					 s_devices[i].ieee_addr[1], s_devices[i].ieee_addr[0]);
			return true;
		}
	}
	return false;
}

zigbee_device_info_t *get_esp_zb_short(const char *ieee_str_in) {
	for (int i = 0; i < s_device_count; i++) {
		const uint8_t *addr = s_devices[i].ieee_addr;
		char ieee_str[17];
		snprintf(ieee_str, sizeof(ieee_str), "%02X%02X%02X%02X%02X%02X%02X%02X",
				 addr[7], addr[6], addr[5], addr[4], addr[3], addr[2], addr[1],
				 addr[0]);

		if (strcmp(ieee_str, ieee_str_in) == 0) {
			return &s_devices[i]; // ✅ 返回地址
		}
	}
	return NULL;
}

/**
 * @brief 注册用户自定义的回调函数
 */
void zigbee_register_callbacks(
	zb_coordinator_start_cb_t on_start, zb_device_join_cb_t on_join,
	zb_device_leave_cb_t on_leave,
	zb_zcl_receive_cb_t zb_attribute_reporting_handler) {
	s_start_cb = on_start;
	s_join_cb = on_join;
	s_leave_cb = on_leave;
	s_receive_cb = zb_attribute_reporting_handler;
}

/**
 * @brief 内部函数：用于触发 Zigbee BDB 顶层组网流程（网络初始化/形成/引导等）
 *
 * @param mode_mask 网络操作类型，例如 ESP_ZB_BDB_MODE_NETWORK_FORMATION
 */
static void bdb_commissioning_cb(uint8_t mode_mask) {
	esp_zb_bdb_start_top_level_commissioning(mode_mask);
}

static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask) {
	ESP_RETURN_ON_FALSE(esp_zb_bdb_start_top_level_commissioning(mode_mask) ==
							ESP_OK,
						, TAG, "Failed to start Zigbee bdb commissioning");
}

/**
 * @brief Zigbee 应用层信号处理函数（系统回调）
 *        用于响应 Zigbee 协议栈的各种状态（如初始化完成、设备入网等）
 *
 * @param signal_struct Zigbee 框架传入的信号结构体
 */
void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct) {
	uint32_t *sg = signal_struct->p_app_signal;
	esp_zb_app_signal_type_t sig = *sg;
	esp_err_t status = signal_struct->esp_err_status;
	esp_zb_zdo_signal_device_annce_params_t *annce_params = NULL;

	switch (sig) {
	case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP:
		esp_zb_bdb_start_top_level_commissioning(
			ESP_ZB_BDB_MODE_INITIALIZATION);
		break;
	case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
	case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
		if (status == ESP_OK) {
			ESP_LOGI(TAG, "Device started up in%s factory-reset mode",
					 esp_zb_bdb_is_factory_new() ? "" : " non");
			if (esp_zb_bdb_is_factory_new()) {
				ESP_LOGI(TAG, "Start network formation");
				esp_zb_bdb_start_top_level_commissioning(
					ESP_ZB_BDB_MODE_NETWORK_FORMATION);
			} else {
				esp_zb_bdb_open_network(180);
				ESP_LOGI(TAG, "Device rebooted");
			}
		} else {
			ESP_LOGW(TAG, "%s failed with status: %s, retrying",
					 esp_zb_zdo_signal_to_string(sig), esp_err_to_name(status));
			esp_zb_scheduler_alarm(
				(esp_zb_callback_t)bdb_start_top_level_commissioning_cb,
				ESP_ZB_BDB_MODE_INITIALIZATION, 1000);
		}

		uint16_t short_addr = esp_zb_get_short_address();
		ESP_LOGI(TAG, "My short address: 0x%04X", short_addr);

		break;
	case ESP_ZB_BDB_SIGNAL_FORMATION:
		if (status == ESP_OK) {
			esp_zb_ieee_addr_t extended_pan_id;
			esp_zb_get_extended_pan_id(extended_pan_id);
#if DEBUG
			ESP_LOGI(TAG,
					 "Formed network successfully (Extended PAN ID: "
					 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: "
					 "0x%04hx, Channel:%d, Short Address: 0x%04hx)",
					 extended_pan_id[7], extended_pan_id[6], extended_pan_id[5],
					 extended_pan_id[4], extended_pan_id[3], extended_pan_id[2],
					 extended_pan_id[1], extended_pan_id[0],
					 esp_zb_get_pan_id(), esp_zb_get_current_channel(),
					 esp_zb_get_short_address());
#endif
			esp_zb_bdb_start_top_level_commissioning(
				ESP_ZB_BDB_MODE_NETWORK_STEERING);
		} else {

#if DEBUG
			ESP_LOGI(TAG, "Restart network formation (status: %s)",
					 esp_err_to_name(status));
#endif
			esp_zb_scheduler_alarm(
				(esp_zb_callback_t)bdb_start_top_level_commissioning_cb,
				ESP_ZB_BDB_MODE_NETWORK_FORMATION, 1000);
		}
		break;
	case ESP_ZB_BDB_SIGNAL_STEERING:
		if (status == ESP_OK) {
			ESP_LOGI(TAG, "Network steering started");
		}
		break;

	case ESP_ZB_ZDO_SIGNAL_DEVICE_ANNCE:
		annce_params = (esp_zb_zdo_signal_device_annce_params_t *)
			esp_zb_app_signal_get_params(sg);
		ESP_LOGI(TAG, "New device commissioned or rejoined (short: 0x%04hx)",
				 annce_params->device_short_addr);
		if (s_join_cb) {
			s_join_cb(annce_params->device_short_addr, annce_params->ieee_addr);
		}
		// 加入设备列表
		if (s_device_count < MAX_DEVICES &&
			!update_device_short_addr_if_exists(
				annce_params->ieee_addr, annce_params->device_short_addr)) {
			s_devices[s_device_count].short_addr =
				annce_params->device_short_addr;
			s_devices[s_device_count].is_online = true;
			s_devices[s_device_count].last_seen_ms = esp_log_timestamp();
			memcpy(s_devices[s_device_count].ieee_addr, annce_params->ieee_addr,
				   8);
			s_device_count++;
			save_devices_to_nvs();
		}
		break;
	case ESP_ZB_NWK_SIGNAL_PERMIT_JOIN_STATUS:
		if (status == ESP_OK) {
			if (*(uint8_t *)esp_zb_app_signal_get_params(sg)) {
				ESP_LOGI(TAG, "Network(0x%04hx) is open for %d seconds",
						 esp_zb_get_pan_id(),
						 *(uint8_t *)esp_zb_app_signal_get_params(sg));
			} else {
				ESP_LOGW(
					TAG,
					"Network(0x%04hx) closed, devices joining not allowed.",
					esp_zb_get_pan_id());
			}
		}
	case ESP_ZB_NLME_STATUS_INDICATION:
		esp_zb_ieee_addr_t extended_pan_id;
		esp_zb_get_extended_pan_id(extended_pan_id);
		ESP_LOGW(TAG,
				 "PAN ID 冲突: "
				 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: "
				 "0x%04hx, Channel:%d, Short Address: 0x%04hx)",
				 extended_pan_id[7], extended_pan_id[6], extended_pan_id[5],
				 extended_pan_id[4], extended_pan_id[3], extended_pan_id[2],
				 extended_pan_id[1], extended_pan_id[0], esp_zb_get_pan_id(),
				 esp_zb_get_current_channel(), esp_zb_get_short_address());

		break;
	default:
		ESP_LOGI(TAG, "未处理 Zigbee 信号: %s (0x%x), 状态: %s",
				 esp_zb_zdo_signal_to_string(sig), sig,
				 esp_err_to_name(status));
		break;
	}
}

bool update_device_short_addr_if_exists(const uint8_t *ieee_addr,
										uint16_t device_short_addr) {
	for (int i = 0; i < s_device_count; i++) {
		if (memcmp(s_devices[i].ieee_addr, ieee_addr, 8) == 0) {
			s_devices[i].short_addr = device_short_addr;
			save_devices_to_nvs();
			return true;
		}
	}
	return false;
}

esp_err_t save_devices_to_nvs(void) {
	nvs_handle_t nvs;
	esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs);
	if (err != ESP_OK) {
		ESP_LOGE("ZB_NVS", "Failed to open NVS: 0x%x", err);
		return err;
	}

	// 写入设备个数
	err = nvs_set_u8(nvs, NVS_KEY_COUNT, (uint8_t)s_device_count);
	if (err != ESP_OK) {
		nvs_close(nvs);
		return err;
	}

	// 写入设备列表为原始二进制 blob
	err = nvs_set_blob(nvs, NVS_KEY_DEVICES, s_devices,
					   sizeof(zigbee_device_info_t) * s_device_count);
	if (err != ESP_OK) {
		nvs_close(nvs);
		return err;
	}

	err = nvs_commit(nvs);
	nvs_close(nvs);
	ESP_LOGI("ZB_NVS", "Saved %d devices to NVS", s_device_count);
	return err;
}

esp_err_t load_devices_from_nvs(void) {
	nvs_handle_t nvs;
	esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs);
	if (err != ESP_OK)
		return err;

	uint8_t count = 0;
	err = nvs_get_u8(nvs, NVS_KEY_COUNT, &count);
	if (err != ESP_OK) {
		nvs_close(nvs);
		return err;
	}

	if (count > MAX_DEVICES)
		count = MAX_DEVICES;
	size_t size = sizeof(zigbee_device_info_t) * count;

	err = nvs_get_blob(nvs, NVS_KEY_DEVICES, s_devices, &size);
	if (err == ESP_OK) {
		s_device_count = count;
		ESP_LOGI("ZB_NVS", "Loaded %d devices from NVS", s_device_count);
	}

	nvs_close(nvs);
	return err;
}

/**
 * @brief Zigbee ZCL 统一设备级回调处理函数（v1.6.0 SDK 推荐）
 *
 *        用于接收来自子设备的 ZCL 命令，例如 On/Off 开关控制命令。
 *        所有接收回调都从这里分发，cb_id 表示收到的是哪一类命令。
 *
 * @param cb_id    SDK 定义的回调类型标识符，例如
 * ESP_ZB_ZCL_ON_OFF_CLUSTER_COMMAND_RECEIVED
 * @param args     实际指令内容指针（根据 cb_id 类型转换结构体）
 */
static bool zigbee_device_cb_handler(uint8_t bufid) {
	zb_zcl_device_callback_param_t *device_cb_param =
		ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);
	zb_uint8_t *payload = zb_buf_begin(bufid);
	zb_uint16_t payload_len = zb_buf_len(bufid);
	zb_zcl_device_cmd_generic_param_t *gnr = &device_cb_param->cb_param.gnr;

	ESP_LOGI(TAG, "ZCL 回调触发，bufid = %d device_cb_id:0x%04X",
			 device_cb_param->device_cb_id, payload_len);
	switch (device_cb_param->device_cb_id) {
		// case ZB_ZCL_CLUSTER_HANDLER_CB_ID:
		//	// 用户自定义集群命令接收回调
		//	if (gnr->in_cmd_info->cluster_id == YOUR_CUSTOM_CLUSTER_ID) {
		//		// payload 是指向自定义命令负载的指针
		//		// payload_len 是负载长度
		//		// 在这里解析 payload，执行相应逻辑
		//	}
		//	break;

	case ZB_ZCL_SET_ATTR_VALUE_CB_ID:
		// 收到属性写请求（比如设置开关状态）
		// device_cb_param->cb_param.set_attr_value_param 包含
		// endpoint、cluster_id、attr_id、value 可以在这里同步 MCU 状态
		break;

	case ZB_ZCL_ON_OFF_WITH_EFFECT_VALUE_CB_ID:
		// 收到开关命令（例如 On、Off 或 Toggle）
		// device_cb_param->cb_param.on_off_effect_value 包含
		// effect_id、effect_variant 可根据 effect_id
		// 处理不同的开关动画（ZCL 6.6.1.4.4.2）
		for (int i = 0; i < s_device_count; i++) {
			if (s_devices[i].short_addr ==
				device_cb_param->cb_param.gnr.in_cmd_info->addr_data.intrp_data
					.src_addr) {
				s_devices[i].is_online = true;
				s_devices[i].last_seen_ms = esp_log_timestamp();
			}
		}
		break;

	case ZB_ZCL_IAS_ZONE_ENROLL_RESPONSE_VALUE_CB_ID:
		// 这是 IAS Zone（烟雾探测器）设备入网时的响应处理
		// device_cb_param->cb_param.enroll_response 包含 enroll response
		// 的详细信息 可以在这里保存入网状态、上报平台
		break;

	case ZB_ZCL_IAS_ACE_EMERGENCY_CB_ID:
		// 这是 IAS ACE 紧急事件处理（比如火灾报警按钮、烟雾报警）
		// 一般用于集中报警控制面板接收 smoke/fire 报警
		// 需要根据实际需求执行本地报警、发送 MQTT、蜂鸣器等动作
		break;
	case ZB_ZCL_NO_REPORTING_CB_ID:
		break;
	default:
		break;
	}

	return RET_OK;
}

/**
 * @brief 通用的 Zigbee ZCL 命令发送函数
 *
 * @param short_addr     目标设备的短地址
 * @param endpoint       目标设备端点（默认一般为 1）
 * @param cluster_id     ZCL 集群 ID（如 0x0006 表示 On/Off）
 * @param command_id     ZCL 命令 ID（如 0x01 表示 ON）
 * @param payload        数据负载指针（如无数据可传 {}）
 * @return esp_err_t     成功返回 ESP_OK
 */
esp_err_t zigbee_send_zcl_command(uint16_t short_addr, uint8_t endpoint,
								  uint16_t cluster_id, uint8_t command_id,
								  const uint8_t *payload) {
#if DEBUG
	esp_zb_ieee_addr_t extended_pan_id;
	esp_zb_get_extended_pan_id(extended_pan_id);
	ESP_LOGI(TAG,
			 "send command short_addr:0x%04X endpoint:%d cluster_id:0x%04X, "
			 "command_id:%d",
			 short_addr, endpoint, cluster_id, command_id);
	ESP_LOGI(TAG,
			 "Joined network successfully (Extended PAN ID: "
			 "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, "
			 "Channel:%d, Short Address: 0x%04hx)",
			 extended_pan_id[7], extended_pan_id[6], extended_pan_id[5],
			 extended_pan_id[4], extended_pan_id[3], extended_pan_id[2],
			 extended_pan_id[1], extended_pan_id[0], esp_zb_get_pan_id(),
			 esp_zb_get_current_channel(), esp_zb_get_short_address());
#endif
	esp_zb_zcl_custom_cluster_cmd_t cmd = {
		.zcl_basic_cmd =
			{
				.dst_addr_u.addr_short = short_addr,
				.dst_endpoint = endpoint,
				.src_endpoint = ESP_ZB_GATEWAY_ENDPOINT,
			},
		.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT,
		.profile_id = ESP_ZB_AF_ZLL_PROFILE_ID, // 通常使用 HA profile
		.cluster_id = cluster_id,				// 自定义集群 ID
		//.manuf_specific = 0,
		.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV,
		//.dis_defalut_resp = 0,
		//.manuf_code = 0x0000,
		.custom_cmd_id = command_id};

	if (payload != NULL) {
		cmd.data.type = ESP_ZB_ZCL_ATTR_TYPE_U8;
		cmd.data.size = sizeof(payload);
		cmd.data.value = &payload;
	}

	esp_zb_lock_acquire(portMAX_DELAY);
	esp_zb_zcl_custom_cluster_cmd_req(&cmd);
	esp_zb_lock_release();
#if DEBUG
	ESP_LOGI(TAG, "ZCL命令已发送: cluster=0x%04X cmd=0x%02X to 0x%04X",
			 cluster_id, command_id, short_addr);
#endif
	return ESP_OK;
}

#if DEBUG
static void simple_desc_cb(esp_zb_zdp_status_t zdo_status,
						   esp_zb_af_simple_desc_1_1_t *simple_desc,
						   void *user_ctx) {
	if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS && simple_desc) {
		ESP_LOGI(TAG, "Simple Desc: ep=%d, profile_id=0x%04X, device_id=0x%04X",
				 simple_desc->endpoint, simple_desc->app_profile_id,
				 simple_desc->app_device_id);

		for (int i = 0; i < simple_desc->app_input_cluster_count; i++) {
			ESP_LOGI(TAG, "  Server Cluster[%d]: 0x%04X", i,
					 simple_desc->app_cluster_list[i]);
		}
	} else {
		ESP_LOGW(TAG, "Simple Descriptor 请求失败，状态: %d", zdo_status);
	}
}
#endif

/**
 * @brief ZDO Active Endpoint 请求的回调函数
 *
 *        当调用 esp_zb_zdo_active_ep_req() 请求某个设备的活动端点列表后，
 *        Zigbee 协议栈会在收到响应时调用这个回调函数。
 *        可以用于判断设备是否在线（是否有回应）。
 *
 * @param zdo_status   ZDO 响应状态，ESP_ZB_ZDP_STATUS_SUCCESS 表示成功
 * @param ep_count     返回的活动端点数量
 * @param ep_id_list   活动端点 ID 列表指针（长度为 ep_count）
 * @param user_ctx     用户自定义上下文（在发起请求时传入的
 * void*），此处为设备信息结构体指针
 */
static void zb_active_ep_cb(esp_zb_zdp_status_t zdo_status, uint8_t ep_count,
							uint8_t *ep_id_list, void *user_ctx) {
	// 将 user_ctx 转回原本的设备信息结构体指针
	zigbee_device_info_t *device_info = (zigbee_device_info_t *)user_ctx;

	switch (zdo_status) {
	case ESP_ZB_ZDP_STATUS_SUCCESS:
		// for (int i = 0; i < ep_count; i++) {
		//	ESP_LOGI(TAG, "设备0x%04X 注册端点：%d", device_info->short_addr,
		//			 ep_id_list[i]);
		//	esp_zb_zdo_simple_desc_req_param_t simple_desc_req = {
		//		.addr_of_interest = device_info->short_addr,
		//		.endpoint =  10
		//	};
		//	esp_zb_zdo_simple_desc_req(&simple_desc_req, simple_desc_cb, NULL);

		//}
		// 设备成功响应，表示在线
		ESP_LOGI(TAG, "device addr：0x%04X online", device_info->short_addr);
		device_info->is_online = true;
		// zigbee_send_zcl_command(device_info->short_addr, 10,
		//						ESP_ZB_ZCL_CLUSTER_ID_ON_OFF,
		//						ESP_ZB_ZCL_CMD_ON_OFF_TOGGLE_ID, NULL);
		if (s_join_cb) {
			s_join_cb(device_info->short_addr, device_info->ieee_addr);
		}

		break;
	case ESP_ZB_ZDP_STATUS_TIMEOUT:
		// 请求超时，设备未回应，可能掉线了
		device_info->is_online = false;
		if (s_leave_cb) {
			s_leave_cb(device_info->short_addr, device_info->ieee_addr);
		}
		break;

	default:
		// 其他错误类型，打印出来辅助调试
		ESP_LOGW(TAG, "device addr：0x%04X zdo_status: %d",
				 device_info->short_addr, zdo_status);
		break;
	}
}

/**
 * @brief 定时 ping 所有已知子设备，用于检测在线状态
 *
 *        通过 Read Attributes 命令读取每个设备的 On/Off 状态属性。
 *        如果发送成功，则认为设备在线；
 *        如果发送失败，则标记为离线。
 */
static void ping_all_devices(void *arg) {
	for (int i = 0; i < s_device_count; i++) {
		uint16_t addr = s_devices[i].short_addr; // 获取子设备短地址

		esp_zb_zdo_active_ep_req_param_t ep_req = {
			.addr_of_interest = addr,
		};

		esp_zb_zdo_active_ep_req(&ep_req, zb_active_ep_cb,
								 (void *)&s_devices[i]);
		ESP_LOGI("ZB_PING", "Ping sent to 0x%04X", addr);
	}

	// 注册定时任务，30 秒后再次执行 ping_all_devices()
	esp_zb_scheduler_alarm(ping_all_devices, NULL, 30000);
}

static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id,
								   const void *message) {
	esp_err_t ret = ESP_OK;
	switch (callback_id) {
	case ESP_ZB_CORE_REPORT_ATTR_CB_ID:
		s_receive_cb(
			(esp_zb_zcl_report_attr_message_t *)
				message); // zb_attribute_reporting_handler((esp_zb_zcl_report_attr_message_t
						  // *)message);
		break;
	case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID:
		// ret =
		// zb_read_attr_resp_handler((esp_zb_zcl_cmd_read_attr_resp_message_t
		// *)message);
		break;
	case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID:
		// ret =
		// zb_configure_report_resp_handler((esp_zb_zcl_cmd_config_report_resp_message_t
		// *)message);
		break;
	default:
		ESP_LOGW(TAG, "Receive Zigbee action(0x%x) callback", callback_id);
		break;
	}
	return ret;
}

/**
 * @brief Zigbee 协调器主任务
 *        负责初始化 Zigbee 协议栈、注册 ZCL 接收处理函数并启动主循环
 */
static void zigbee_main_task(void *pv) {

	esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);
	esp_zb_cfg_t cfg = ESP_ZB_ZC_CONFIG();

	esp_zb_init(&cfg);

	esp_zb_ep_list_t *ep_list = esp_zb_ep_list_create();
	esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create();
	esp_zb_endpoint_config_t endpoint_config = {
		.endpoint = ESP_ZB_GATEWAY_ENDPOINT,
		.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
		.app_device_id = ESP_ZB_HA_REMOTE_CONTROL_DEVICE_ID,
		.app_device_version = 0};

	esp_zb_attribute_list_t *basic_cluster = esp_zb_basic_cluster_create(NULL);
	esp_zb_basic_cluster_add_attr(basic_cluster,
								  ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID,
								  ESP_MANUFACTURER_NAME);
	esp_zb_basic_cluster_add_attr(basic_cluster,
								  ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID,
								  ESP_MODEL_IDENTIFIER);

	esp_zb_cluster_list_add_basic_cluster(cluster_list, basic_cluster,
										  ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
	esp_zb_cluster_list_add_identify_cluster(
		cluster_list, esp_zb_identify_cluster_create(NULL),
		ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
	esp_zb_cluster_list_add_thermostat_cluster(
		cluster_list, esp_zb_thermostat_cluster_create(NULL),
		ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);

	// esp_zb_attribute_list_t *custome_cluster =
	// esp_zb_zcl_attr_list_create(0x0408);
	// esp_zb_cluster_add_attr(custome_cluster,0x0408,0x0001,ESP_ZB_ZCL_ATTR_TYPE_8BIT,ESP_ZB_ZCL_ATTR_ACCESS_READ_WRITE,NULL);
	// esp_zb_cluster_list_add_custom_cluster(cluster_list, custome_cluster,
	// ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);  // 接收端是 Client
	//  esp_zb_endpoint_config_t ep_cfg = {
	//	.endpoint = 1,
	//	.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
	//	.app_device_version = 0,
	// };
	// esp_zb_ep_list_t *ep = esp_zb_ep_list_create();
	// esp_zb_ep_list_add_ep(ep, cluster_list, ep_cfg);

	/* Create customized temperature sensor endpoint */
	esp_zb_cluster_list_add_temperature_meas_cluster(
		cluster_list, esp_zb_temperature_meas_cluster_create(NULL),
		ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
	esp_zb_cluster_list_add_humidity_meas_cluster(
		cluster_list, esp_zb_humidity_meas_cluster_create(NULL),
		ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
	esp_zb_cluster_list_add_illuminance_meas_cluster(
		cluster_list, esp_zb_illuminance_meas_cluster_create(NULL),
		ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
	esp_zb_cluster_list_add_custom_cluster(cluster_list,
										   esp_zb_zcl_attr_list_create(0xFC01),
										   ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);

	esp_zb_cluster_list_add_on_off_cluster(
		cluster_list, esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_ON_OFF),
		ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);

	// esp_zb_cluster_list_add_on_off_cluster(cluster_list,esp_zb_on_off_cluster_create(NULL),ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
	esp_zb_ep_list_add_ep(ep_list, cluster_list, endpoint_config);
	// esp_zb_ep_list_add_gateway_ep(ep_list, cluster_list, endpoint_config);

	// 打印集群
	esp_zb_cluster_list_t *cp_cluster_list =
		esp_zb_ep_list_get_ep(ep_list, ESP_ZB_GATEWAY_ENDPOINT);
	while (cp_cluster_list != NULL) {
		esp_zb_zcl_cluster_t cl = cp_cluster_list->cluster;
		ESP_LOGI(TAG, " clusterID: 0x%04X  role:0x%04X manuf_code:%d",
				 cl.cluster_id, cl.role_mask, cl.manuf_code);
		cp_cluster_list = cp_cluster_list->next;
	}

	// 注册设备层事件回调
	esp_zb_device_cb_id_handler_register(zigbee_device_cb_handler);
	// 注册ZCL命令/网络层事件回调
	esp_zb_core_action_handler_register(zb_action_handler);

	esp_zb_cli_resp_handler_register(zigbee_device_cb_handler);
	// 注册集群
	esp_zb_device_register(ep_list);

	// 启动 Zigbee 协议栈（false = 非阻塞）
	ESP_ERROR_CHECK(esp_zb_start(false));

	// 启动设备在线状态检查
	esp_zb_scheduler_alarm(ping_all_devices, NULL, 30000);
	// 进入 Zigbee 协议主循环（阻塞）
	esp_zb_main_loop_iteration();
}

/**
 * @brief 初始化 Zigbee 协调器并创建主任务
 */
esp_err_t zigbee_manager_init(void) {
	load_devices_from_nvs();
	esp_zb_platform_config_t platform_cfg = {
		.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
		.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
	};

	// 初始化平台配置（Zigbee 串口/驱动/设备配置）
	ESP_ERROR_CHECK(esp_zb_platform_config(&platform_cfg));

	// 创建 Zigbee 主任务
	xTaskCreate(zigbee_main_task, "zb_main", 4096, NULL, 5, NULL);
	return ESP_OK;
}